package com.dishdex.menuhub.module.utils;

import com.alibaba.fastjson2.JSON;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.*;


public final class PersonJwt {
    private static final Charset UTF8 = StandardCharsets.UTF_8;
    private static final String key = "1234567890abcdef";          // 16 字节
    private static final SecretKeySpec keySpec =
            new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

    private PersonJwt() {
    }

    /* 对象 -> JSON -> AES 加密 -> Base64 URL（带随机 IV） */
    public static String packObject(Object object) throws Exception {
        Objects.requireNonNull(object, "object to pack must not be null");

        // 1. 生成 16 字节随机 IV
        byte[] ivBytes = new byte[16];
        SecureRandom sr = new SecureRandom();
        sr.nextBytes(ivBytes);
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        // 2. Object -> JSON
        String json = JSON.toJSONString(object);

        // 3. JSON -> AES Encrypt
        Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        encryptCipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encrypted = encryptCipher.doFinal(json.getBytes(UTF8));

        // 4. 拼接：IV + 密文
        byte[] ivAndCipher = ByteBuffer.allocate(ivBytes.length + encrypted.length)
                .put(ivBytes)
                .put(encrypted)
                .array();

        // 5. Base64 URL 编码
        return Base64.getUrlEncoder().withoutPadding().encodeToString(ivAndCipher);
    }

    /* Base64 URL -> 截取 IV -> AES 解密 -> 反 JSON -> 对象 */
    public static <T> T unpackString(String sign, Class<T> clazz) throws Exception {
        // 1. Base64 URL 解码
        byte[] ivAndCipher = Base64.getUrlDecoder().decode(sign);
        if (ivAndCipher.length < 17) throw new IllegalArgumentException("bad input");

        // 2. 截取前 16 字节作为 IV
        byte[] ivBytes = Arrays.copyOfRange(ivAndCipher, 0, 16);
        byte[] cipher = Arrays.copyOfRange(ivAndCipher, 16, ivAndCipher.length);
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        // 3. AES 解密
        Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] aesDecoded = decryptCipher.doFinal(cipher);

        // 4. 转 UTF-8 字符串
        String jsonPlain = new String(aesDecoded, StandardCharsets.UTF_8);

        // 5. JSON -> 对象
        return JSON.parseObject(jsonPlain, clazz);
    }
}
